package com.wms.shop.service.impl;

import java.math.BigDecimal;
import java.util.List;
import java.util.Arrays;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.google.common.collect.Maps;
import com.wms.common.core.exception.CustomException;
import com.wms.common.core.utils.DateUtils;
import com.wms.common.redis.service.RedisService;
import com.wms.shop.domain.Address;
import com.wms.shop.domain.Order;
import com.wms.shop.domain.OrderItem;
import com.wms.shop.domain.User;
import com.wms.shop.domain.vo.PayOrderVo;
import com.wms.shop.domain.vo.SkuVo;
import com.wms.shop.enums.DeliveryStatus;
import com.wms.shop.enums.OrderStatus;
import com.wms.shop.enums.PayStatus;
import com.wms.shop.mapper.AddressMapper;
import com.wms.shop.mapper.OrderItemMapper;
import com.wms.shop.mapper.OrderMapper;
import com.wms.shop.mapper.UserMapper;
import com.wms.shop.service.IOrderService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wms.common.core.utils.SecurityUtils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * 商城订单Service业务层处理
 *
 * @author zzm
 * @date 2021-12-19
 */
@Service
public class OrderServiceImpl implements IOrderService
{
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private RedisService redisService;


    @Autowired
    private WxPayService wxService;

    @Autowired
    private AddressMapper addressMapper;

    @Autowired
    private UserMapper userMapper;

    /**
     * 查询商城订单
     *
     * @param id 商城订单ID
     * @return 商城订单
     */
    @Override
    public Order selectOrderById(Long id)
    {
        Order order = orderMapper.selectById(id);
        if (order.getAddressId() != null) {
            Address address = addressMapper.selectById(order.getAddressId());
            order.setAddress(address);
            if (StringUtils.isNotEmpty(order.getStatus())) {
                order.setStatusDesc(OrderStatus.parse(order.getStatus()).getName());
            }
            if (StringUtils.isNotEmpty(order.getPayStatus())) {
                order.setPayStatusDesc(PayStatus.parse(order.getPayStatus()).getName());
            }
            if (StringUtils.isNotEmpty(order.getDeliveryStatus())) {
                order.setDeliveryStatusDesc(DeliveryStatus.parse(order.getDeliveryStatus()).getName());
            }
            User user = userMapper.selectById(order.getUserId());
            order.setUser(user);
        }
        LambdaQueryWrapper<OrderItem> orderItemLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderItemLambdaQueryWrapper.eq(OrderItem::getOrderId, id);
        orderItemLambdaQueryWrapper.eq(OrderItem::getDelFlag, Boolean.FALSE);
        List<OrderItem> orderItems = orderItemMapper.selectList(orderItemLambdaQueryWrapper);
        order.setOrderItemList(orderItems);
        return order;
    }

    /**
     *
     * @param sn 商城订单订单号
     * @return
     */
    @Override
    public Order selectOrderBySn(String sn) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("sn", sn);
        return orderMapper.selectOne(queryWrapper);
    }

    @Override
    public List<Order> selectOrderList(Order order) {
        LambdaQueryWrapper<Order> orderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        List<Order> orders = orderMapper.selectList(orderLambdaQueryWrapper);
        return orders;
    }

    /**
     * 查询商城订单列表
     *
     * @param order 商城订单
     * @return 商城订单
     */
    @Override
    public List<Order> selectWxOrderList(Order order)
    {
        LambdaQueryWrapper<Order> orderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderLambdaQueryWrapper.eq(Order::getUserId, order.getUserId());
        orderLambdaQueryWrapper.eq(Order::getDelFlag, Boolean.FALSE);
        if (StringUtils.isNotEmpty(order.getStatus())) {
            orderLambdaQueryWrapper.eq(Order::getStatus, order.getStatus());
        }
        List<Order> orders = orderMapper.selectList(orderLambdaQueryWrapper);
        if (CollectionUtils.isNotEmpty(orders)) {
            for (Order o : orders) {
                Address address = addressMapper.selectById(o.getAddressId());
                o.setAddress(address);
                LambdaQueryWrapper<OrderItem> orderItemLambdaQueryWrapper = new LambdaQueryWrapper<>();
                orderItemLambdaQueryWrapper.eq(OrderItem::getOrderId, o.getId());
                orderItemLambdaQueryWrapper.eq(OrderItem::getDelFlag, Boolean.FALSE);
                List<OrderItem> orderItems = orderItemMapper.selectList(orderItemLambdaQueryWrapper);
                o.setOrderItemList(orderItems);
                o.setStatusDesc(OrderStatus.parse(o.getStatus()).getName());
            }
        }
        return orders;
    }

    /**
     * 新增商城订单
     *
     * @param order 商城订单
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Order insertOrder(PayOrderVo payOrderVo) {
        Order order  =  new Order();
        order.setCreateBy(SecurityUtils.getUsername());
        order.setUserId(SecurityUtils.getUserId());
        BigDecimal totalAmount = BigDecimal.ZERO;
        order.setSn("SO"+DateUtils.getNowDate().getTime());
        order.setDelFlag(Boolean.FALSE);
        order.setCreateBy(SecurityUtils.getUsername());
        order.setCreateTime(DateUtils.getNowDate());
        order.setInventoryType("2");
        order.setPayStatus(PayStatus.NO.getValue());
        order.setStatus(OrderStatus.WAIT_PAY.getValue());
        for (SkuVo skuVo : payOrderVo.getSkus()){
            totalAmount = totalAmount.add(skuVo.getSalesPrice().multiply(skuVo.getQuantity()));
        }
        order.setTotalAmount(totalAmount);
        order.setAddressId(payOrderVo.getUserAddressId());
        orderMapper.insert(order);
        for (SkuVo skuVo : payOrderVo.getSkus()) {
//            Long qty = redisService.redisTemplate.opsForValue().decrement(orderItem.getSkuSn(), orderItem.getQty());
//            if(qty < 0){
//                redisService.redisTemplate.opsForValue().increment(orderItem.getSkuSn(), orderItem.getQty());
//                throw new CustomException("库存不足!");
//            }
            OrderItem orderItem = new OrderItem();
            orderItem.setQty(skuVo.getQuantity());
            orderItem.setPrice(skuVo.getSalesPrice());
            orderItem.setAmount(orderItem.getPrice().multiply(orderItem.getQty()));
            orderItem.setImages(skuVo.getImages());
            orderItem.setProductName(skuVo.getProductName());
            orderItem.setDelFlag(Boolean.FALSE);
            orderItem.setCreateTime(order.getCreateTime());
            orderItem.setCreateBy(order.getCreateBy());
            orderItem.setOrderId(order.getId());
            orderItem.setSkuId(skuVo.getSkuId());
            orderItemMapper.insert(orderItem);
        }

//        if (r < 0) {
//            // 还原库存
//            for (OrderItem orderItem : order.getOrderItemList()) {
//                redisService.redisTemplate.opsForValue().increment(orderItem.getSkuSn(), orderItem.getQty());
//            }
//        }


        // 发起请求获取支付的参数
//        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
//        request.setOutTradeNo(order.getSn());
//        request.setBody("test");
//        request.setOpenid("oUpF8uMuAJO_M2pxb1Q9zNjWeS6o");
//        request.setTradeType("JSAPI");
//        request.setSpbillCreateIp("192.16.0.1");
//        request.setNotifyUrl("https://www.baidu.com");
//        request.setTotalFee(order.getTotalAmount().multiply(new BigDecimal(100)).intValue());
//
//        try {
//            // 返回的支付参数
//            WxPayMpOrderResult wxPayMpOrderResult = wxService.createOrder(request);
//            return wxPayMpOrderResult;
//        }catch (Exception e)
//        {
//            // 还原库存
//            for (OrderItem orderItem : order.getOrderItemList()) {
//                redisService.redisTemplate.opsForValue().increment(orderItem.getSkuSn(), orderItem.getQty());
//            }
//            throw new CustomException(e.toString());
//        }
        return order;
    }

    /**
     * 修改商城订单
     *
     * @param order 商城订单
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateOrder(Order order)
    {
        order.setUpdateBy(SecurityUtils.getUsername());
        order.setUpdateTime(DateUtils.getNowDate());
        List<OrderItem> orderItems = order.getOrderItemList();
        if (CollectionUtils.isNotEmpty(orderItems)) {
            for (OrderItem orderItem : orderItems) {
                Assert.notNull(orderItem.getWarehouseId(), "仓库不能为空!");
                orderItem.setUpdateBy(order.getUpdateBy());
                orderItem.setUpdateTime(order.getUpdateTime());
                orderItemMapper.updateById(orderItem);
            }
        }
        return orderMapper.updateById(order);
    }

    /**
     * 批量删除商城订单
     *
     * @param ids 需要删除的商城订单ID
     * @return 结果
     */
    @Override
    public int deleteOrderByIds(Long[] ids)
    {
        Order order = new Order();
        order.setDelFlag(Boolean.TRUE);
        order.setUpdateTime(DateUtils.getNowDate());
        order.setUpdateBy(SecurityUtils.getUsername());
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id",Arrays.asList(ids));
        return orderMapper.update(order, queryWrapper);
    }

    /**
     * 删除商城订单信息
     *
     * @param id 商城订单ID
     * @return 结果
     */
    @Override
    public int deleteOrderById(Long id)
    {
        return orderMapper.deleteById(id);
    }

    @Override
    public int cancel(Long id) {
        LambdaQueryWrapper<Order> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Order::getId, id);
        Order oldObj = orderMapper.selectById(id);
        Assert.notNull(oldObj, "订单不存在!");
        if (!OrderStatus.WAIT_PAY.getValue().equals(oldObj.getStatus())) {
            throw new CustomException("订单状态异常,请联系管理员!");
        }
        Order upFrm = new Order();
        upFrm.setStatus(OrderStatus.CANCEL.getValue());
        orderMapper.update(upFrm, lambdaQueryWrapper);
        return 1;
    }

    @Override
    public int receive(Long id) {
        LambdaQueryWrapper<Order> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Order::getId, id);
        Order oldObj = orderMapper.selectById(id);
        Assert.notNull(oldObj, "订单不存在!");
        if (!OrderStatus.WAIT_RECEIVE.getValue().equals(oldObj.getStatus())) {
            throw new CustomException("订单状态异常,请联系管理员!");
        }
        Order upFrm = new Order();
        upFrm.setStatus(OrderStatus.FINISH.getValue());
        upFrm.setDeliveryStatus(DeliveryStatus.SIGN.getValue());
        orderMapper.update(upFrm, lambdaQueryWrapper);
        return 1;
    }


    @Override
    public List<Integer> countAllOrders() {
        List<Integer> allCounts = Lists.newArrayList();

        LambdaQueryWrapper<Order> orderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderLambdaQueryWrapper.eq(Order::getUserId, SecurityUtils.getUserId());
        orderLambdaQueryWrapper.eq(Order::getStatus, OrderStatus.WAIT_PAY.getValue());
        orderLambdaQueryWrapper.eq(Order::getDelFlag, Boolean.FALSE);
        Integer waitPayNum = orderMapper.selectCount(orderLambdaQueryWrapper);
        allCounts.add(waitPayNum);


        LambdaQueryWrapper<Order> orderLambdaQueryWrapper2 = new LambdaQueryWrapper<>();
        orderLambdaQueryWrapper2.eq(Order::getUserId, SecurityUtils.getUserId());
        orderLambdaQueryWrapper2.eq(Order::getStatus, OrderStatus.WAIT_SEND.getValue());
        orderLambdaQueryWrapper2.eq(Order::getDelFlag, Boolean.FALSE);
        Integer waitSendNum = orderMapper.selectCount(orderLambdaQueryWrapper2);
        allCounts.add(waitSendNum);


        LambdaQueryWrapper<Order> orderLambdaQueryWrapper3 = new LambdaQueryWrapper<>();
        orderLambdaQueryWrapper3.eq(Order::getStatus, OrderStatus.WAIT_RECEIVE.getValue());
        orderLambdaQueryWrapper3.eq(Order::getUserId, SecurityUtils.getUserId());
        orderLambdaQueryWrapper3.eq(Order::getDelFlag, Boolean.FALSE);
        Integer waitReceiveNum = orderMapper.selectCount(orderLambdaQueryWrapper3);
        allCounts.add(waitReceiveNum);


        LambdaQueryWrapper<Order> orderLambdaQueryWrapper4 = new LambdaQueryWrapper<>();
        orderLambdaQueryWrapper4.eq(Order::getUserId, SecurityUtils.getUserId());
        orderLambdaQueryWrapper4.eq(Order::getStatus, OrderStatus.FINISH.getValue());
        orderLambdaQueryWrapper4.eq(Order::getDelFlag, Boolean.FALSE);
        Integer finishNum = orderMapper.selectCount(orderLambdaQueryWrapper4);
        allCounts.add(finishNum);

        return allCounts;
    }
}
